home *** CD-ROM | disk | FTP | other *** search
- # Copyright (c) 2004-2005 Gentoo Foundation
- # Distributed under the terms of the GNU General Public License v2
- # $Header$
-
- # Contributed by Roy Marples (uberlord@gentoo.org)
- # Many thanks to all the people in the Gentoo forums for their ideas and
- # motivation for me to make this and keep on improving it
-
- # Fix any potential localisation problems
- # Note that LC_ALL trumps LC_anything_else according to locale(7)
- iwconfig() {
- LC_ALL=C /sbin/iwconfig "$@"
- }
- iwgetid() {
- LC_ALL=C /sbin/iwgetid "$@"
- }
- iwlist() {
- LC_ALL=C /sbin/iwlist "$@"
- }
- iwpriv() {
- LC_ALL=C /sbin/iwpriv "$@"
- }
-
- # void iwconfig_depend(void)
- #
- # Sets up the dependancies for the module
- iwconfig_depend() {
- before interface
- }
-
- # bool iwconfig_check_installed(void)
- #
- # Returns 1 if wireless-tools is installed, otherwise 0
- iwconfig_check_installed() {
- [[ -x /sbin/iwconfig ]] && return 0
- ${1:-false} && eerror "For Wireless (802.11) support, emerge net-wireless/wireless-tools"
- return 1
- }
-
- # char* iwconfig_provides(void)
- #
- # Returns a string to change module definition for starting up
- iwconfig_provides() {
- echo "wireless"
- }
-
- # bool iwconfig_check_depends(void)
- #
- # Checks to see if we have the needed functions
- iwconfig_check_depends() {
- local f
-
- for f in interface_variable interface_up interface_down interface_exists; do
- [[ $( type -t ${f} ) == function ]] && continue
- eerror "iwconfig: missing required function ${f}\n"
- return 1
- done
-
- return 0
- }
-
- # bool iwconfig_check_extensions(char *interface)
- #
- # Checks to see if wireless extensions are enabled on the interface
- iwconfig_check_extensions() {
- local iface=${1}
-
- # Do we have wireless extensions enabled on the interface?
- local ext=$( iwconfig ${iface} 2>/dev/null | awk -v iface=${iface} '{ if ($1 == iface) print "yes" }' )
- [[ ${ext} == yes ]]
- return $?
- }
-
- # char* iwconfig_get_wep_status(char *interface)
- #
- # Echos a string showing whether WEP is enabled or disabled
- # for the given interface
- iwconfig_get_wep_status() {
- local wep_status=$( iwconfig ${1} | awk -F: '/Encryption key:/ {print $2}' | awk '{if ($1 != "off") print "enabled"}' ) mode
- wep_status=${wep_status:-"disabled"}
-
- [[ ${wep_status} == enabled ]] && mode=" - $( iwconfig ${1} | awk -F: '/Security mode:/ {print $3}' )"
-
- echo "(WEP ${wep_status}${mode})"
- }
-
- # char* iwconfig_get_essid(char *iface)
- #
- # Gets the current ESSID of the iface
- iwconfig_get_essid() {
- # Too many users are having with iwgetid atm :/
- # iwgetid -r
-
- local i essid
-
- for (( i=0; i<5; i++ )); do
- essid=$( iwconfig $1 2>/dev/null | awk -F\" '/ESSID/ {print $2}' )
- if [[ -n ${essid} ]]; then
- echo ${essid}
- return 0
- fi
- sleep 1
- done
-
- return 1
- }
-
- # char* iwconfig_get_ap_mac_address(char *interface)
- #
- # Returns the MAC address of the Access Point
- # the interface is connected to
- iwconfig_get_ap_mac_address() {
- iwgetid --ap ${1} 2>${devnull}| awk '{print $4}'
- }
-
- # char* iwconfig_get_mode(char *interface)
- #
- # Returns the wireless mode in lower case
- iwconfig_get_mode() {
- iwgetid --mode ${1} | awk -F: '{print $2}' | tr '[:upper:]' '[:lower:]'
- }
-
- # char* iwconfig_get_type(char *interface)
- #
- # Returns the type of interface - the IEEE part
- iwconfig_get_type() {
- iwconfig ${1} 2>/dev/null | awk '{print $2,$3}'
- }
-
- # void iwconfig_report(char *interface)
- #
- # Output how our wireless interface has been configured
- iwconfig_report() {
- local iface=${1} essid i=0 mac m="to"
-
- essid=$( iwconfig_get_essid ${iface} )
-
- local wep_status=$( iwconfig_get_wep_status ${iface} )
- local channel=$( iwgetid --channel 2>/dev/null | cut -d: -f2 )
- [[ -n ${channel} ]] && channel="on channel ${channel} "
-
- essid=${essid//\\\\/\\\\}
- local mode=$( iwconfig_get_mode ${iface} )
- if [[ ${mode} == "master" ]]; then
- m="as"
- else
- mac=$( iwconfig_get_ap_mac_address ${iface} )
- [[ -n ${mac} ]] && mac=" at ${mac}"
- fi
-
- eindent
- einfo "${iface} connected ${m} \"${essid}\"${mac}"
- einfo "in ${mode} mode ${channel}${wep_status}"
- eoutdent
- }
-
- # char* iwconfig_get_wep_key(char *mac_address)
- #
- # Returns the configured WEP key for the given mac address
- # or the given ESSID. The mac address setting takes precendence
- iwconfig_get_wep_key() {
- local mac=${1} key
- eval key=\"\${mac_key_${mac//:/}\}\"
- [[ -z ${key} ]] && eval key=\"\${key_${ESSIDVAR}\}\"
- key=${key:-"off"}
- echo ${key}
- }
-
- # void iwconfig_user_config(char *iface)
- #
- # Applies the user configuration to the interface
- iwconfig_user_config() {
- local iface=${1} conf e ifvar=$( interface_variable ${1} )
-
- # Apply the user configuration
- eval conf=\"\$\{iwconfig_${ifvar}\}\"
- if [[ -n ${conf} ]]; then
- e=$( iwconfig ${iface} ${conf} 2>&1 )
- if [[ -n ${e} ]]; then
- ewarn "${iface} does not support the following configuration commands"
- ewarn " \"${conf}\""
- fi
- fi
-
- eval conf=\"\$\{iwpriv_${ifvar}\}\"
- if [[ -n ${conf} ]]; then
- e=$( iwpriv ${iface} ${conf} 2>&1 )
- if [[ -n ${e} ]]; then
- ewarn "${iface} does not support the following private ioctls"
- ewarn " \"${conf}\""
- fi
- fi
- }
-
- # bool iwconfig_setup_specific(char *iface)
- #
- # Sets up our wireless interface to operate in ad-hoc or master mode
- iwconfig_setup_specific() {
- local iface=${1} mode=${2} channel key dessid e
- local ifvar=$( interface_variable ${1} )
-
- if [[ -z ${ESSID} ]]; then
- eerror "${iface} requires an ESSID to be set to operate in ${mode} mode"
- eerror "adjust the essid_${iface} setting in /etc/conf.d/wireless"
- return 1
- fi
- dessid=${ESSID//\\\\/\\\\}
- LC_ALL=C ESSIDVAR=${ESSID//[![:word:]]/_}
-
- # We only change the mode if it's not the same
- local cur_mode=$( iwconfig_get_mode ${iface} )
- if [[ ${cur_mode} != ${mode} ]]; then
- e=$( iwconfig ${iface} mode ${mode} 2>&1 )
- if [[ -n ${e} ]]; then
- eerror "${iface} does not support setting the mode to \"${mode}\""
- return 1
- fi
- fi
-
- key=$( iwconfig_get_wep_key )
- e=$( eval "iwconfig ${iface} key ${key} 2>&1" )
- if [[ -n ${e} && ${key} != off ]]; then
- ewarn "${iface} does not support setting keys"
- ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect"
- fi
-
- e=$( iwconfig ${iface} essid "${ESSID}" 2>&1 )
- if [[ -n ${e} ]]; then
- eerror "${iface} does not support setting ESSID to \"${dessid}\""
- return 1
- fi
- iwconfig ${iface} nick "${ESSID}" 2>/dev/null
-
- eval channel=\"\$\{channel_${ifvar}\}\"
- # We default the channel to 3
- channel=${channel:-3}
-
- e=$( iwconfig ${iface} channel ${channel} 2>&1 )
- if [[ -n ${e} ]]; then
- eerror ${e}
- ewarn "${iface} does not support setting the channel to \"${channel}\""
- return 1
- fi
-
- iwconfig_user_config ${iface}
- iwconfig_report ${iface}
-
- return 0
- }
-
- # bool iwconfig_associate_mac(char *iface)
- #
- # Returns true if the AP MAC address is valid or not
- iwconfig_associate_mac() {
- # Checks if a MAC address has been assigned
- local mac=$( iwconfig_get_ap_mac_address ${1} ) i
- local -a invalid_macs=( "00:00:00:00:00:00" "44:44:44:44:44:44" "FF:00:00:00:00:00" "FF:FF:FF:FF:FF:FF" )
-
- [[ -z ${mac} ]] && return 1
- for i in ${invalid_macs[@]}; do
- [[ ${i} == ${mac} ]] && return 1
- done
- return 0
- }
-
- # bool iwconfig_associate_quality(char *iface)
- #
- # Returns true if the link quality is not 0 or 0.
- iwconfig_associate_quality() {
- local quality=$( cat /proc/net/wireless | awk -v IFACE=${1}: '{ if ($1 == IFACE) print $3 }' )
- [[ ${quality} != 0 && ${quality} != 0. ]] && return 0
- return 1
- }
-
- # bool iwconfig_test_associated(char *iface)
- #
- # Returns true if the interface has associated with an Access Point
- iwconfig_test_associated() {
- local iface=${1} test ifvar=$( interface_variable ${1} )
- # Some drivers don't set MAC to a bogus value when assocation is lost/fails
- # whereas they do set link quality to 0
-
- test=$( eval echo \$\{associate_test_${ifvar}\} | tr '[:upper:]' '[:lower:]' )
- test=${test:-mac}
- if [[ ${test} != mac && ${test} != quality && ${test} != all ]]; then
- ewarn " associate_test_${iface} is not set to mac, quality or all"
- ewarn " defaulting to \"mac\""
- test=mac
- fi
-
- case ${test} in
- mac) iwconfig_associate_mac ${iface} && return 0 ;;
- quality) iwconfig_associate_quality ${iface} && return 0 ;;
- all) iwconfig_associate_mac ${iface} && iwconfig_associate_quality ${iface} && return 0 ;;
- esac
-
- return 1
- }
-
- # bool iwconfig_wait_for_association(char *iface)
- #
- # Waits for a configured ammount of time until
- # we are assocaited with an Access Point
- iwconfig_wait_for_association() {
- local iface=${1} i=0 wait ifvar=$( interface_variable ${1} )
- eval wait=\"\$\{sleep_associate_${ifvar}\}\"
- wait=${wait:-10}
-
- while (( i<wait )); do
- iwconfig_test_associated ${iface} && return 0
- sleep 1
- (( i++ ))
- done
- return 1
- }
-
- # bool iwconfig_associate(char *interface, char *mac_address, char *wep_required)
- #
- # Tries to associate the interface with an Access Point
- # If we scanned the Access Point we know if we need WEP to associate or not
- # and if we have a WEP key for the ESSID or not
- # so we can fail gracefully without even trying to connect
- iwconfig_associate() {
- local iface=${1} mac=${2} wep_required=${3} w="(WEP Disabled)"
- local dessid=${ESSID//\\\\/\\\\} key
- wep_required=${wep_required:-"off"}
-
- if [[ ${ESSID} == any ]]; then
- iwconfig ${iface} ap any 2>/dev/null
- dessid="any"
- unset ESSIDVAR
- else
- LC_ALL=C ESSIDVAR=${ESSID//[![:word:]]/_}
- key=$( iwconfig_get_wep_key ${mac} )
- if [[ ${wep_required} == yes && ${key} == off ]]; then
- vewarn "WEP key is not set for \"${dessid}\" - not connecting"
- return 1
- fi
- if [[ ${wep_required} == no && ${key} != off ]]; then
- key="off"
- vewarn "\"${dessid}\" is not WEP enabled - ignoring setting"
- fi
-
- e=$( eval "iwconfig ${iface} key ${key} 2>&1" )
- if [[ -n ${e} && ${key} != off ]]; then
- ewarn "${iface} does not support setting keys"
- ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect"
- return 1
- fi
- [[ ${key} != off ]] && w=$( iwconfig_get_wep_status ${iface} )
- fi
-
- e=$( iwconfig ${iface} essid "${ESSID}" 2>&1 )
- [[ -n ${e} && ${ESSID} != any ]] && ewarn "${iface} does not support setting ESSID to \"${dessid}\""
- iwconfig ${iface} nick "${ESSID}" 2>/dev/null
-
- vebegin "Connecting to \"${dessid}\" ${w}"
-
- if [[ ${ESSID} != any && $( type -t preassociate ) == function ]]; then
- local essidx=${ESSID} essidvarx=${ESSIDVAR}
- veinfo "Running preassociate function"
- eindent
- preassociate ${iface} ; e=$?
- eoutdent
- if [[ ${e} != 0 ]]; then
- veend 1 "preassociate \"${dessid}\" on ${iface} failed"
- return 1
- fi
- ESSID=${essidx} ESSIDVAR=${essidvarx}
- fi
-
- if ! iwconfig_wait_for_association ${iface} ; then
- veend 1
- return 1
- fi
- veend 0
-
- if [[ ${ESSID} == any ]]; then
- ESSID=$( iwconfig_get_essid ${iface} )
- iwconfig_associate ${iface}
- return $?
- fi
-
- iwconfig_user_config ${iface}
- iwconfig_report ${iface}
-
- if [[ $( type -t postassociate ) == function ]]; then
- local essidx=${ESSID} essidvarx=${ESSIDVAR}
- veinfo "Running postassociate function"
- eindent
- postassociate ${iface}
- eoutdent
- ESSID=${essidx} ESSIDVAR=${essidvarx}
- fi
-
- return 0
- }
-
- # bool iwconfig_scan(char *iface)
- #
- # Fills 3 arrays with information from a wireless scan
- iwconfig_scan() {
- local iface=${1} e mode x ifvar=$( interface_variable ${1} )
-
- # First, we may need to change mode to scan in
- mode=$( eval echo \$\{scan_mode_${ifvar}\} | tr '[:upper:]' '[:lower:]' )
- if [[ -n ${mode} ]]; then
- e=$( iwconfig ${iface} mode ${mode} 2>&1 )
- [[ -n ${e} ]] && ewarn "${iface} does not support setting the mode to \"${mode}\""
- fi
-
- # Next we set any private driver ioctls needed
- eval x=\"\$\{iwpriv_scan_pre_${ifvar}\}\"
- if [[ -n ${x} ]]; then
- e=$( iwpriv ${iface} ${x} 2>&1 )
- if [[ -n ${e} ]]; then
- ewarn "${iface} does not support the following private ioctls" \
- ewarn " \"${x}\""
- fi
- fi
-
- veinfo "Scanning for access points"
-
- # Sleep if required
- eval x=\"\$\{sleep_scan_${ifvar}\}\"
- [[ -n ${x} ]] && sleep ${x}
-
- local scan=$( iwlist ${iface} scanning 2>/dev/null )
-
- # We may need to unset the previous private driver ioctls
- eval x=\"\$\{iwpriv_scan_post_${ifvar}\}\"
- if [[ -n ${x} ]]; then
- e=$( iwpriv ${iface} ${x} 2>&1 )
- if [[ -n ${e} ]]; then
- ewarn "${iface} does not support the following private ioctls" \
- ewarn " \"${x}\""
- fi
- fi
-
- # Change back mode if needed
- x=$( eval echo \$\{mode_${ifvar}\} | tr '[:upper:]' '[:lower:]' )
- x=${x:-auto}
- [[ ${mode} != ${x} ]] && iwconfig ${iface} mode ${x} &>/dev/null
-
- # HUP the interface as some drivers/cards need it
- interface_down ${iface}
- interface_up ${iface}
-
- if [[ -z ${scan} ]]; then
- ewarn "${iface} does not support scanning"
- eval x=\"\$\{adhoc_essid_${ifvar}\}\"
- [[ -n ${x} ]] && return 0
- if [[ -n ${preferred_aps} ]]; then
- [[ ${associate_order} == forcepreferred \
- || ${associate_order} == forcepreferredonly ]] && return 0
- fi
- eerror "You either need to set a preferred_aps list in /etc/conf.d/wireless"
- eerror " preferred_aps=( \"ESSID1\" \"ESSID2\" )"
- eerror " and set associate_order_${iface}=\"forcepreferred\""
- eerror " or set associate_order_${iface}=\"forcepreferredonly\""
- eerror "or hardcode the ESSID to \"any\" and let the driver find an Access Point"
- eerror " essid_${iface}=\"any\""
- eerror "or configure defaulting to Ad-Hoc when Managed fails"
- eerror " adhoc_essid_${iface}=\"WLAN\""
- eerror "or hardcode the ESSID against the interface (not recommended)"
- eerror " essid_${iface}=\"ESSID\""
- return 1
- fi
-
- local val i=-1 IFS=$'\n' j last
- local -a qual
-
- # OK - we need ESSID, MAC address and encryption from just one call to iwlist $iface scan
- # It has to be one call for speed reasons as some cards take ages to get a list from
- # It's clumsy (imo) but it works
- for val in ${scan}; do
- local t=$( echo ${val} | awk -F: '/ESSID/ {print $2}' )
- if [[ ${#t} -gt 2 ]]; then
- t=${t#*\"}
- essid_APs[i]=${t%*\"}
- else
- t=$( echo ${val} | awk '/Address/ {print}' | sed 's/^.*\<\(..:..:..:..:..:..\)\>.*$/\1/g' )
- if [[ ${#t} -gt 0 ]]; then
- ((i++))
- mac_APs[i]=${t}
- essid_APs[i]=""
- enc_APs[i]=no
- qual[i]=0
- else
- t=$( echo ${val} | awk -F: '/Encryption key/ {print $2}' )
- if [[ ${#t} -gt 0 ]]; then
- if [[ ${t} == off ]]; then
- enc_APs[i]=no
- else
- enc_APs[i]=yes
- fi
- else
- t=$( echo ${val} | awk -F: '/Quality/ {print $2}' )
- if [[ ${#t} -gt 0 ]]; then
- # Not all drivers report the same way, so we take the below measure
- # to ensure we don't error on the sort below
- t=${t# *}
- t=${t%/*}
- t=${t//[![:digit:]]/}
- qual[i]=${t:-0}
- fi
- fi
- fi
- fi
- done
-
- # Now sort the AP's by quality
- for ((last=${#mac_APs[@]}-1; last>0; last--)); do
- for ((i=0; i<${last}; i++)); do
- (( j = i + 1 ))
- if [[ ${qual[i]} -lt ${qual[j]} ]]; then
- t=${mac_APs[i]}
- mac_APs[i]=${mac_APs[j]}
- mac_APs[j]=${t}
- t=${essid_APs[i]}
- essid_APs[i]=${essid_APs[j]}
- essid_APs[j]=${t}
- t=${enc_APs[i]}
- enc_APs[i]=${enc_APs[j]}
- enc_APs[j]=${t}
- t=${qual[i]}
- qual[i]=${qual[j]}
- qual[j]=${t}
- fi
- done
- done
-
- return 0
- }
-
- # void iwconfig_scan_report(void)
- #
- # Report the results of the scan and re-map any ESSIDs if they
- # have been configured for the MAC address found
- iwconfig_scan_report() {
- local i k m remove
- local -a u
-
- [[ -z ${mac_APs} ]] && ewarn " no access points found"
-
- # We need to do the for loop like this so we can
- # dynamically remove from the array
- eindent
- for ((i=0; i<${#mac_APs[@]}; i++)); do
- k=""
- [[ ${enc_APs[i]} == yes ]] && k="(WEP required)"
-
- if [[ -z ${essid_APs[i]} ]]; then
- veinfo "Found ${mac_APs[i]} ${k}"
- else
- veinfo "Found \"${essid_APs[i]//\\\\/\\\\}\" at ${mac_APs[i]} ${k}"
- fi
-
- eindent
-
- eval m=\"\$\{mac_essid_${mac_APs[i]//:/}\}\"
- if [[ -n ${m} ]]; then
- essid_APs[i]=${m}
- veinfo "mapping to \"${m//\\\\/\\\\}\""
- fi
-
- remove=false
- # If we don't know the essid then we cannot connect to them
- # so we remove them from our array
- if [[ -z ${essid_APs[i]} ]]; then
- remove=true
- else
- for k in "${blacklist_aps[@]}"; do
- if [[ ${k} == ${essid_APs[i]} ]]; then
- vewarn "\"${k//\\\\/\\\\}\" has been blacklisted - not connecting"
- remove=true
- break
- fi
- done
- fi
-
- eoutdent
-
- ${remove} && u=( "${u[@]}" "${i}" )
- done
-
- eoutdent
-
- # Now we remove any duplicates
- for ((i=0; i < ${#essid_APs[@]} - 1; i++)); do
- for ((j=${i} + 1; j <${#essid_APs[@]}; j++)); do
- [[ ${essid_APs[i]} == ${essid_APs[j]} ]] && u=( "${u[@]}" "${j}" )
- done
- done
-
- for i in ${u[@]}; do
- unset essid_APs[i]
- unset mac_APs[i]
- unset enc_APs[i]
- done
-
- # We need to squash our arrays so indexes work again
- essid_APs=( "${essid_APs[@]}" )
- mac_APs=( "${mac_APs[@]}" )
- enc_APs=( "${enc_APs[@]}" )
- }
-
- # bool iwconfig_force_preferred(char *iface)
- #
- # Forces the preferred_aps list to associate in order
- # but only if they were not picked up by our scan
- iwconfig_force_preferred() {
- local iface=${1} essid i
-
- [[ -z ${preferred_aps} ]] && return 1
-
- ewarn "Trying to force preferred in case they are hidden"
- for essid in "${preferred_aps[@]}"; do
- local found_AP=false
- for ((i = 0; i < ${#mac_APs[@]}; i++)); do
- if [[ ${essid} == ${essid_APs[i]} ]]; then
- found_AP=true
- break
- fi
- done
- if ! ${found_AP} ; then
- ESSID=${essid}
- iwconfig_associate ${iface} && return 0
- fi
- done
-
- ewarn "Failed to associate with any preferred access points on ${iface}"
- return 1
- }
-
- # bool iwconfig_connect_preferred(char *iface)
- #
- # Connects to preferred_aps in order if they were picked up
- # by our scan
- iwconfig_connect_preferred() {
- local iface=${1} essid i
-
- for essid in "${preferred_aps[@]}"; do
- for ((i=0; i<${#essid_APs[@]}; i++)); do
- if [[ ${essid} == ${essid_APs[i]} ]]; then
- ESSID=${essid}
- iwconfig_associate ${iface} ${mac_APs[i]} ${enc_APs[i]} && return 0
- break
- fi
- done
- done
-
- return 1
- }
-
- # bool iwconfig_connect_not_preferred(char *iface)
- #
- # Connects to any AP's found that are not in
- # our preferred list
- iwconfig_connect_not_preferred() {
- local iface=${1} i ap has_preferred
-
- for ((i=0; i<${#mac_APs[@]}; i++)); do
- has_preferred=false
- for ap in "${preferred_aps[@]}"; do
- if [[ ${ap} == ${essid_APs[i]} ]]; then
- has_preferred=true
- break
- fi
- done
- if ! ${has_preferred} ; then
- ESSID=${essid_APs[i]}
- iwconfig_associate ${iface} ${mac_APs[i]} ${enc_APs[i]} && return 0
- fi
- done
-
- return 1
- }
-
- # void iwconfig_defaults(char *iface)
- #
- # Apply some sane defaults to the wireless interface
- # incase the user already applied some changes
- iwconfig_defaults() {
- local iface=${1}
-
- # Set some defaults
- iwconfig ${iface} rate auto &>/dev/null
- iwconfig ${iface} rts off &>/dev/null
- iwconfig ${iface} frag off &>/dev/null
- iwconfig ${iface} power off &>/dev/null
- iwconfig ${iface} txpower auto &>/dev/null
- iwconfig ${iface} key off [1] &>/dev/null
-
- # We need to set the essid to any as some drivers won't
- # scan correctly if they are already set to an ESSID
- iwconfig ${iface} essid any &>/dev/null
- }
-
- # void iwconfig_strip_associated(char *iface)
- #
- # We check to see which ifaces have associated AP's except for the iface
- # given and remove those AP's from the scan list
- # We also remove from the preferred list
- iwconfig_strip_associated() {
- local iface=${1} e a j
- local essid=$( iwconfig ${iface} | awk -F\" '/ESSID/ {print $2}' )
- local -a ifaces=( $( iwconfig 2>/dev/null | awk '/ESSID/ {print $1}' | awk -v IFACE=${iface} '$1!=IFACE {print}' ) )
-
- for i in "${ifaces[@]}"; do
- interface_is_up ${i} || continue
- iwconfig_test_associated ${i} || continue
- e=$( iwconfig ${i} | awk -F\" '/ESSID/ {print $2}' )
- u=()
- for ((j=0; j<${#mac_APs[@]}; j++)); do
- if [[ ${essid_APs[j]} == ${e} ]]; then
- ewarn "${e} has already been associated with ${i}"
- unset essid_APs[j]
- unset mac_APs[j]
- unset enc_APs[j]
- # We need to squash our arrays so that indexes work
- essid_APs=( "${essid_APs[@]}" )
- mac_APs=( "${mac_APs[@]}" )
- enc_APs=( "${enc_APs[@]}" )
- break
- fi
- done
- for ((j=0; j<${#preferred_aps[@]}; j++)); do
- if [[ ${preferred_aps[j]} == ${e} ]]; then
- unset preferred_aps[j]
- preferred_aps=( "${preferred_aps[@]}" )
- break
- fi
- done
- done
- }
-
- # bool iwconfig_configure(char *iface)
- #
- # The main startup code
- # First we bring the interface up, apply defaults, apply user configuration
- # Then we test to see if ad-hoc mode has been requested and branch if needed
- # Then we scan for access points and try to connect to them in a predetermined order
- # Once we're connected we show a report and then configure any interface
- # variables for the ESSID
- iwconfig_configure() {
- local iface=${1} test x e ifvar=$( interface_variable ${1} )
- local -a essid_APs mac_APs enc_APs
-
- # We need to bring the interface up to apply stuff
- interface_up ${iface}
-
- # Are we a proper IEEE device?
- # Most devices reutrn IEEE 802.11b/g - but intel cards return IEEE in lower case
- # and RA cards return RAPCI or similar which really sucks :(
- # For the time being, we will test prism54 not loading firmware which reports
- # NOT READY!
- x=$( iwconfig_get_type ${iface} )
- if [[ ${x} == "NOT READY!" ]]; then
- eerror "Looks like there was a probem loading the firmware for ${iface}"
- return 1
- fi
-
- iwconfig_defaults ${iface}
- iwconfig_user_config ${iface}
-
- eval ESSID=\"\$\{essid_${ifvar}\}\"
-
- # Setup ad-hoc mode?
- x=$( eval echo \$\{mode_${ifvar}\} | tr '[:upper:]' '[:lower:]' )
- x=${x:-managed}
- if [[ ${x} == ad-hoc || ${x} == master ]]; then
- iwconfig_setup_specific ${iface} ${x}
- return $?
- fi
-
- if [[ ${x} != managed && ${x} != auto ]]; then
- eerror "Only managed, ad-hoc, master and auto modes are supported"
- return 1
- fi
-
- # We only change the mode if it's not the same as some drivers
- # only do managed and throw an error changing to managed
- local cur_mode=$( iwconfig_get_mode ${iface} )
- if [[ ${cur_mode} != ${x} ]]; then
- e=$( iwconfig ${iface} mode ${x} 2>&1 )
- if [[ -n ${e} && ${x} != managed ]]; then
- eerror "${iface} does not support setting the mode to \"${x}\""
- return 1
- fi
- fi
-
- # These arrays hold the results of our scan
- local -a mac_APs essid_APs enc_APs
-
- # Has an ESSID been forced?
- if [[ -n ${ESSID} ]]; then
- iwconfig_associate ${iface} && return 0
- [[ ${ESSID} == any ]] && iwconfig_force_preferred ${iface} && return 0
- eval ESSID=\"\$\{adhoc_essid_${ifvar}\}\"
- if [[ -n ${ESSID} ]]; then
- iwconfig_setup_specific ${iface} ad-hoc
- return $?
- fi
- return 1
- fi
-
- # Do we have a preferred Access Point list specific to the interface?
- eval x=( \"\$\{preferred_aps_${ifvar}\[@\]\}\" )
- [[ -n ${x} ]] && preferred_aps=( "${x[@]}" )
-
- # Do we have a blacklist Access Point list specific to the interface?
- eval x=( \"\$\{blacklist_aps_${ifvar}\[@\]\}\" )
- [[ -n ${e} ]] && blacklist_aps=( "${x[@]}" )
-
- # Are we forcing preferred only?
- eval x=\"\$\{associate_order_${ifvar}\}\"
- [[ -n ${x} ]] && associate_order=${x}
- associate_order=$( echo ${associate_order:-any} | tr '[:upper:]' '[:lower:]' )
-
- if [[ ${associate_order} == forcepreferredonly ]]; then
- iwconfig_force_preferred ${iface} && return 0
- else
- iwconfig_scan ${iface} || return 1
- iwconfig_scan_report
-
- # Strip AP's from the list that have already been associated with
- # other wireless cards in the system if requested
- eval x=\"\$\{unique_ap_${ifvar}\}\"
- [[ -n ${x} ]] && unique_ap=${x}
- unique_ap=$( echo ${unique_ap:-no} | tr '[:upper:]' '[:lower:]' )
- [[ ${unique_ap} != no ]] && iwconfig_strip_associated ${iface}
-
- iwconfig_connect_preferred ${iface} && return 0
- [[ ${associate_order} == forcepreferred || ${associate_order} == forceany ]] && iwconfig_force_preferred ${iface} && return 0
- [[ ${associate_order} == any || ${associate_order} == forceany ]] && iwconfig_connect_not_preferred ${iface} && return 0
- fi
-
- e="associate with"
- [[ -z ${mac_APs} ]] && e="find"
- [[ ${preferred_only} == force || ${preferred_aps} == forceonly ]] && e="force"
- e="Couldn't ${e} any access points on ${iface}"
-
- eval ESSID=\"\$\{adhoc_essid_${ifvar}\}\"
- if [[ -n ${ESSID} ]]; then
- ewarn "${e}"
- iwconfig_setup_specific ${iface} ad-hoc
- return $?
- fi
-
- eerror ${e}
- return 1
- }
-
- # bool iwconfig_pre_start(char *iface)
- #
- # Start entry point
- # First we check if wireless extensions exist on the interface
- # If they are then we configue wireless
- iwconfig_pre_start() {
- local iface=${1} r=0 local wasup=true
-
- interface_exists ${iface} || return 0
-
- if ! iwconfig_check_extensions ${iface} ; then
- if ! interface_is_up ${iface} ; then
- interface_up ${iface}
- wasup=false
- fi
- if ! iwconfig_check_extensions ${iface} ; then
- veinfo "Wireless extensions not found for ${iface}"
- ! ${wasup} && interface_down ${iface}
- return 0
- fi
- fi
-
- einfo "Configuring wireless network for ${iface}"
-
- # Setup IFS incase parent script has modified it
- local IFS=$' '$'\n'$'\t'
-
- iwconfig_configure ${iface} && return 0
-
- eerror "Failed to configure wireless for ${iface}"
- iwconfig_defaults ${iface}
- unset ESSID
- interface_down ${iface}
- return 1
- }
-